package probability;

import army.Army;

public class Probability {

	Army army;
	private double[] probability;
	private double[] distributionTable;
	private int numOfBattleUnits;
	private int distributionArraySize;
	int[] binaryMask;

	public Probability(Army army) {
		this.army = army;

		// not all of units in Army can shoot,
		// so they didn't participate in hits probability distribution
		numOfBattleUnits = army.getArmySize() - army.getUnitsInSquad(0);

		// distr[0]- nobody hits ..
		// distr[distrArrSize] - all units hit the targets
		// so there are +1
		distributionArraySize = numOfBattleUnits + 1;

		getProbabilitiesArray();

		distributionTable = new double[distributionArraySize];
		binaryMask = new int[numOfBattleUnits];
	}

	public void getProbabilitiesArray() {
		probability = new double[numOfBattleUnits];
		int index = 0;
		for (int unitLevel = Army.FIRST_ATTACK_SQUAD; unitLevel < Army.NSQUADS; unitLevel++) {

			for (int unit = 0; unit < army.getUnitsInSquad(unitLevel); unit++) {
				probability[index++] = unitLevel / 6.0;
			}
		}
	}

	public void calculateDistribution() {
		double res;
		int permutations = (int) Math.pow(2, numOfBattleUnits);

		for (int i = 0; i < permutations; i++) {
			res = 1;
			getBinaryMaskArray(i);
		
			for (int j = 0; j < numOfBattleUnits; j++) {
				res *= binaryMask[j] == 1 ? probability[j] : 1 - probability[j];
			}

			distributionTable[howManyHitsInPermutation(i)] += res;
		}
	}
	
	public double mathExpectation(){
		double res=0;
		for (int i = 0; i < distributionArraySize; i++) {
			res+= i*distributionTable[i];
		}
		return res;
	}

	private int howManyHitsInPermutation(int i) {
		int sum = 0;
		for (int j = 0; j < numOfBattleUnits; j++) {
			sum += binaryMask[j];
		}
		return sum;
	}

	public void getBinaryMaskArray(int n) {
		for (int i = 0; i < numOfBattleUnits; i++) {
			binaryMask[i] = (n % 2) > 0 ? 1 : 0;
			n /= 2;
		}
	}

	public void printDistribution() {
		for (int i = 0; i < distributionArraySize; i++) {
			System.out.printf("%2d hits -  %f\n", i, distributionTable[i]);
		}
	}

	public double checkDistribution() {
		double sum = 0;
		for (int i = 0; i < distributionArraySize; i++) {
			sum += distributionTable[i];
		}
		return sum;
	}

}
